home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / ircii2-6.zip / SRC\IRCII-2.6\SOURCE\LASTLOG.C < prev    next >
C/C++ Source or Header  |  1994-12-28  |  8KB  |  388 lines

  1. /*
  2.  * lastlog.c: handles the lastlog features of irc. 
  3.  *
  4.  * Written By Michael Sandrof
  5.  *
  6.  * Copyright(c) 1990 
  7.  *
  8.  * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT 
  9.  */
  10.  
  11. #ifndef lint
  12. static    char    rcsid[] = "@(#)$Id: lastlog.c,v 1.8 1994/07/02 02:32:13 mrg Stab $";
  13. #endif
  14.  
  15. #include "irc.h"
  16.  
  17. #include "lastlog.h"
  18. #include "window.h"
  19. #include "screen.h"
  20. #include "vars.h"
  21. #include "ircaux.h"
  22. #include "output.h"
  23.  
  24. /*
  25.  * lastlog_level: current bitmap setting of which things should be stored in
  26.  * the lastlog.  The LOG_MSG, LOG_NOTICE, etc., defines tell more about this 
  27.  */
  28. static    int    lastlog_level;
  29. static    int    notify_level;
  30.  
  31. /*
  32.  * msg_level: the mask for the current message level.  What?  Did he really
  33.  * say that?  This is set in the set_lastlog_msg_level() routine as it
  34.  * compared to the lastlog_level variable to see if what ever is being added
  35.  * should actually be added 
  36.  */
  37. static    int    msg_level = LOG_CRAP;
  38.  
  39. #define NUMBER_OF_LEVELS 16
  40. static    char    *levels[] =
  41. {
  42.     "CRAP",        "PUBLIC",    "MSGS",        "NOTICES",
  43.     "WALLS",    "WALLOPS",    "NOTES",    "OPNOTES",
  44.     "SNOTES",    "ACTIONS",    "DCC",        "CTCP",
  45.     "USERLOG1",    "USERLOG2",    "USERLOG3",    "USERLOG4"
  46. };
  47.  
  48. /*
  49.  * bits_to_lastlog_level: converts the bitmap of lastlog levels into a nice
  50.  * string format.  Note that this uses the global buffer, so watch out 
  51.  */
  52. char    *bits_to_lastlog_level(level)
  53. int    level;
  54. {
  55.     static    char    buffer[81]; /* this *should* be enough for this */
  56.     int    i,
  57.         p;
  58.  
  59.     if (level == LOG_ALL)
  60.         strcpy(buffer, "ALL");
  61.     else if (level == 0)
  62.         strcpy(buffer, "NONE");
  63.     else
  64.     {
  65.         *buffer = '\0';
  66.         for (i = 0, p = 1; i < NUMBER_OF_LEVELS; i++, p *= 2)
  67.         {
  68.             if (level & p)
  69.             {
  70.                 strmcat(buffer, levels[i],80);
  71.                 strmcat(buffer, " ",80);
  72.             }
  73.         }
  74.     }
  75.     return (buffer);
  76. }
  77.  
  78. int    parse_lastlog_level(str)
  79. char    *str;
  80. {
  81.     char    *ptr,
  82.         *rest;
  83.     int    len,
  84.         i,
  85.         p,
  86.         level,
  87.         neg;
  88.  
  89.     level = 0;
  90.     while ((str = next_arg(str, &rest)) != NULL)
  91.     {
  92.         while (str)
  93.         {
  94.             if ((ptr = index(str, ',')) != NULL)
  95.                 *ptr++ = '\0';
  96.             if ((len = strlen(str)) != 0)
  97.             {
  98.                 if (my_strnicmp(str, "ALL", len) == 0)
  99.                     level = LOG_ALL;
  100.                 else if (my_strnicmp(str, "NONE", len) == 0)
  101.                     level = 0;
  102.                 else
  103.                 {
  104.                     if (*str == '-')
  105.                     {
  106.                         str++;
  107.                         neg = 1;
  108.                     }
  109.                     else
  110.                         neg = 0;
  111.                     for (i = 0, p = 1; i < NUMBER_OF_LEVELS;
  112.                             i++, p *= 2)
  113.                     {
  114.                         if (!my_strnicmp(str, levels[i],
  115.                                 len))
  116.                         {
  117.                             if (neg)
  118.                                 level &=
  119.                                   (LOG_ALL ^ p);
  120.                             else
  121.                                 level |= p;
  122.                             break;
  123.                         }
  124.                     }
  125.                     if (i == NUMBER_OF_LEVELS)
  126.                         say("Unknown lastlog level: %s",
  127.                             str);
  128.                 }
  129.             }
  130.             str = ptr;
  131.         }
  132.         str = rest;
  133.     }
  134.     return (level);
  135. }
  136.  
  137. /*
  138.  * set_lastlog_level: called whenever a "SET LASTLOG_LEVEL" is done.  It
  139.  * parses the settings and sets the lastlog_level variable appropriately.  It
  140.  * also rewrites the LASTLOG_LEVEL variable to make it look nice 
  141.  */
  142. void    set_lastlog_level(str)
  143. char    *str;
  144. {
  145.     lastlog_level = parse_lastlog_level(str);
  146.     set_string_var(LASTLOG_LEVEL_VAR, bits_to_lastlog_level(lastlog_level));
  147.     curr_scr_win->lastlog_level = lastlog_level;
  148. }
  149.  
  150. static    void    remove_from_lastlog(window)
  151. Window    *window;
  152. {
  153.     Lastlog *tmp;
  154.  
  155.     if (window->lastlog_tail)
  156.     {
  157.         tmp = window->lastlog_tail->prev;
  158.         new_free(&window->lastlog_tail->msg);
  159.         new_free(&window->lastlog_tail);
  160.         window->lastlog_tail = tmp;
  161.         if (tmp)
  162.             tmp->next = (Lastlog *) 0;
  163.         else
  164.             window->lastlog_head = window->lastlog_tail;
  165.         window->lastlog_size--;
  166.     }
  167.     else
  168.         window->lastlog_size = 0;
  169. }
  170.  
  171. /*
  172.  * set_lastlog_size: sets up a lastlog buffer of size given.  If the lastlog
  173.  * has gotten larger than it was before, all previous lastlog entry remain.
  174.  * If it get smaller, some are deleted from the end. 
  175.  */
  176. void    set_lastlog_size(size)
  177. int    size;
  178. {
  179.     int    i,
  180.         diff;
  181.  
  182.     if (curr_scr_win->lastlog_size > size)
  183.     {
  184.         diff = curr_scr_win->lastlog_size - size;
  185.         for (i = 0; i < diff; i++)
  186.             remove_from_lastlog(curr_scr_win);
  187.     }
  188. }
  189.  
  190. /*
  191.  * lastlog: the /LASTLOG command.  Displays the lastlog to the screen. If
  192.  * args contains a valid integer, only that many lastlog entries are shown
  193.  * (if the value is less than lastlog_size), otherwise the entire lastlog is
  194.  * displayed 
  195.  */
  196. /*ARGSUSED*/
  197. void    lastlog(command, args)
  198. char    *command,
  199.     *args;
  200. {
  201.     int    cnt,
  202.         from = 0,
  203.         p,
  204.         i,
  205.         level = 0,
  206.         msg_level,
  207.         len,
  208.         mask = 0,
  209.         header = 1;
  210.     Lastlog *start_pos;
  211.     char    *match = NULL,
  212.         *arg;
  213.  
  214.     message_from((char *) 0, LOG_CURRENT);
  215.     cnt = curr_scr_win->lastlog_size;
  216.  
  217.     while ((arg = next_arg(args, &args)) != NULL)
  218.     {
  219.         if (*arg == '-')
  220.         {
  221.             arg++;
  222.             if (!(len = strlen(arg)))
  223.                 header = 0;
  224.             else if (!my_strnicmp(arg, "LITERAL", len))
  225.             {
  226.                 if (match)
  227.                 {
  228.                     say("Second -LITERAL argument ignored");
  229.                     (void) next_arg(args, &args);
  230.                     continue;
  231.                 }
  232.                 if ((match = next_arg(args, &args)) != NULL)
  233.                     continue;
  234.                 say("Need pattern for -LITERAL");
  235.                 return;
  236.             }
  237.             else
  238.             {
  239.                 for (i = 0, p = 1; i < NUMBER_OF_LEVELS; i++,
  240.                         p *= 2)
  241.                 {
  242.                     if (my_strnicmp(levels[i], arg, len) == 0)
  243.                     {
  244.                         mask |= p;
  245.                         break;
  246.                     }
  247.                 }
  248.                 if (i == NUMBER_OF_LEVELS)
  249.                 {
  250.                     say("Unknown flag: %s", arg);
  251.                     message_from((char *) 0, LOG_CRAP);
  252.                     return;
  253.                 }
  254.             }
  255.         }
  256.         else
  257.         {
  258.             if (level == 0)
  259.             {
  260.                 if (match || isdigit(*arg))
  261.                 {
  262.                     cnt = atoi(arg);
  263.                     level++;
  264.                 }
  265.                 else
  266.                     match = arg;
  267.             }
  268.             else if (level == 1)
  269.             {
  270.                 from = atoi(arg);
  271.                 level++;
  272.             }
  273.         }
  274.     }
  275.     start_pos = curr_scr_win->lastlog_head;
  276.     for (i = 0; (i < from) && start_pos; start_pos = start_pos->next)
  277.         if (!mask || (mask & start_pos->level))
  278.             i++;
  279.  
  280.     for (i = 0; (i < cnt) && start_pos; start_pos = start_pos->next)
  281.         if (!mask || (mask & start_pos->level))
  282.             i++;
  283.  
  284.     level = curr_scr_win->lastlog_level;
  285.     msg_level = set_lastlog_msg_level(0);
  286.     if (start_pos == (Lastlog *) 0)
  287.         start_pos = curr_scr_win->lastlog_tail;
  288.     else
  289.         start_pos = start_pos->prev;
  290.  
  291.     /* Let's not get confused here, display a seperator.. -lynx */
  292.     if (header)
  293.         say("Lastlog:");
  294.     for (i = 0; (i < cnt) && start_pos; start_pos = start_pos->prev)
  295.     {
  296.         if (!mask || (mask & start_pos->level))
  297.         {
  298.             i++;
  299.             if (match)
  300.             {
  301.                 if (scanstr(start_pos->msg, match))
  302.                     put_it("%s", start_pos->msg);
  303.             }
  304.             else
  305.                 put_it("%s", start_pos->msg);
  306.         }
  307.     }
  308.     if (header)
  309.         say("End of Lastlog");
  310.     curr_scr_win->lastlog_level = level;
  311.     set_lastlog_msg_level(msg_level);
  312.     message_from((char *) 0, LOG_CRAP);
  313. }
  314.  
  315. /* set_lastlog_msg_level: sets the message level for recording in the lastlog */
  316. int    set_lastlog_msg_level(level)
  317. int    level;
  318. {
  319.     int    old;
  320.  
  321.     old = msg_level;
  322.     msg_level = level;
  323.     return (old);
  324. }
  325.  
  326. /*
  327.  * add_to_lastlog: adds the line to the lastlog.  If the LASTLOG_CONVERSATION
  328.  * variable is on, then only those lines that are user messages (private
  329.  * messages, channel messages, wall's, and any outgoing messages) are
  330.  * recorded, otherwise, everything is recorded 
  331.  */
  332. void    add_to_lastlog(window, line)
  333. Window    *window;
  334. char    *line;
  335. {
  336.     Lastlog *new;
  337.  
  338.     if (window == (Window *) 0)
  339.         window = curr_scr_win;
  340.     if (window->lastlog_level & msg_level)
  341.     {
  342.         /* no nulls or empty lines (they contain "> ") */
  343.         if (line && (strlen(line) > 2))
  344.         {
  345.             new = (Lastlog *) new_malloc(sizeof(Lastlog));
  346.             new->next = window->lastlog_head;
  347.             new->prev = (Lastlog *) 0;
  348.             new->level = msg_level;
  349.             new->msg = (char *) 0;
  350.             malloc_strcpy(&(new->msg), line);
  351.  
  352.             if (window->lastlog_head)
  353.                 window->lastlog_head->prev = new;
  354.             window->lastlog_head = new;
  355.  
  356.             if (window->lastlog_tail == (Lastlog *) 0)
  357.                 window->lastlog_tail = window->lastlog_head;
  358.  
  359.             if (window->lastlog_size++ == get_int_var(LASTLOG_VAR))
  360.                 remove_from_lastlog(window);
  361.         }
  362.     }
  363. }
  364.  
  365. int    islogged(window)
  366. Window    *window;
  367. {
  368.     return (window->lastlog_level & msg_level) ? 1 : 0;
  369. }
  370.  
  371. int    real_notify_level()
  372. {
  373.     return (notify_level);
  374. }
  375.  
  376. int    real_lastlog_level()
  377. {
  378.     return (lastlog_level);
  379. }
  380.  
  381. void    set_notify_level(str)
  382. char    *str;
  383. {
  384.     notify_level = parse_lastlog_level(str);
  385.     set_string_var(NOTIFY_LEVEL_VAR, bits_to_lastlog_level(notify_level));
  386.     curr_scr_win->notify_level = notify_level;
  387. }
  388.